#include "facedetect.h"

FaceDectect::FaceDectect (const std::string modelpath, std::string id) {
    name = id;
    detector = FaceDetectorYN::create (modelpath, "", Size (320, 320),
        0.8,  // 置信度阈值 score_threshold
        0.65, // 非极大值抑制阈值 nms_threshold
        5000  // 最大检测数量 top_k
    );
    if (detector.empty ()) {
        std::cerr << "load mode " << modelpath << " failed!" << std::endl;
    }
}

FaceDectect::~FaceDectect () {}

void FaceDectect::Run (const Mat &input,Mat& output) {
    int   width = input.cols;
    int   height = input.rows;
    detector->setInputSize (Size (width, height));
    detector->detect (input, output);

#if 1
    printf ("face: %d %d\n", width, height);
    Mat faces = output.clone ();
    Mat image = input.clone ();
    imwrite ("outx.jpg", image);

    if (!faces.empty ()) {
        std::cout << "检测到 " << faces.rows << " 张人脸" << std::endl;

        // 遍历每张人脸
        for (int i = 0; i < faces.rows; i++) {
            // 解析人脸框（前4个值：x, y, w, h）
            float *face_data = faces.ptr<float> (i);
            int    x = static_cast<int> (face_data[0]);
            int    y = static_cast<int> (face_data[1]);
            int    w = static_cast<int> (face_data[2]);
            int    h = static_cast<int> (face_data[3]);

            // 解析关键点（第4-13个值，共5个点，每个点2个坐标）
            Point2i right_eye (static_cast<int> (face_data[4]), static_cast<int> (face_data[5]));
            Point2i left_eye (static_cast<int> (face_data[6]), static_cast<int> (face_data[7]));
            Point2i nose (static_cast<int> (face_data[8]), static_cast<int> (face_data[9]));
            Point2i right_mouth (static_cast<int> (face_data[10]), static_cast<int> (face_data[11]));
            Point2i left_mouth (static_cast<int> (face_data[12]), static_cast<int> (face_data[13]));

            // 绘制人脸框（绿色，线宽2）
            rectangle (image, Rect (x, y, w, h), Scalar (0, 255, 0), 2);

            // 绘制关键点（颜色与Python代码一致）
            circle (image, right_eye, 3, Scalar (0, 0, 255), -1);     // 右眼红色
            circle (image, left_eye, 3, Scalar (255, 0, 0), -1);      // 左眼蓝色
            circle (image, nose, 3, Scalar (0, 255, 0), -1);          // 鼻子绿色
            circle (image, right_mouth, 3, Scalar (255, 255, 0), -1); // 右嘴角青色
            circle (image, left_mouth, 3, Scalar (0, 255, 255), -1);  // 左嘴角色
        }
    } else {
        std::cout << "未检测到人脸" << std::endl;
    }

    // ------------------------- 6. 保存结果图像 -------------------------
    imwrite ("out.jpg", image);
#endif
}

/**
 *   col: box(x) box(y) box(w) box(h) right_eye(x,y) left_eye(x,y) nose(x,y) right_mouth(x,y) left_mouth(x,y)
 *   row: face numbers
 */

#ifdef DEBUG_FACE
int main (int argc, char *argv[]) {
    const std::string modelpath = "model/face/yunet_n_320_320.onnx";
    FaceDectect       faces (modelpath);
    Mat               image = imread ("test_face.jpg");
    if (image.empty ()) {
        std::cerr << "无法加载图像" << std::endl;
        return -1;
    }
    faces.Run (image);
    return 0;
}
#endif
// g++ -std=c++11 facedetect.cpp -o facedetect -L /home/android/opencv/build/install/usr/local/lib `pkg-config --cflags
// --libs opencv4` -DDEBUG_FACE=1 export LD_LIBRARY_PATH=/home/android/opencv/build/install/usr/local/lib
